package com.alex.monitor.core.rule.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.alex.monitor.core.annotation.MethodMonitor;
import com.alex.monitor.core.rule.MonitorRule;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Map;

/**
 * 默认预警规则
 *
 * @author Alex.Liu
 * @date: 2025-02-16 16:22
 * @since 1.0.0
 */
public class DefaultMonitorRule implements MonitorRule {

    /**
     * 匹配方法监控的结果
     *
     * @param annotation 方法监控注解
     * @param result     方法执行结果
     * @return 是否匹配
     */
    @Override
    public boolean match(Method method, MethodMonitor annotation, Object result) {
        // 根据结果类型进行不同的匹配逻辑
        if (result instanceof Boolean) {
            return result.equals(Boolean.valueOf(annotation.result()));
        }
        if (result instanceof Integer) {
            return result.equals(Integer.valueOf(annotation.result()));
        }
        if (result instanceof Long) {
            return result.equals(Long.valueOf(annotation.result()));
        }
        if (result instanceof Double) {
            return result.equals(Double.valueOf(annotation.result()));
        }
        if (result instanceof BigDecimal) {
            return result.equals(new BigDecimal(annotation.result()));
        }
        if (result instanceof String) {
            return result.equals(annotation.result());
        }
        if (result instanceof Map) {
            // 对于Map类型，从Map中获取指定key的值进行比较
            String str = MapUtil.getStr((Map<?, ?>) result, annotation.code());
            return StrUtil.equals(str, annotation.result());
        }
        // 返回obj 类型的 转换成map 检查是否有该属性，如果有是否该属性值满足
        try {
            JSONObject map = new JSONObject(BeanUtil.beanToMap(result));
            if (map.containsKey(annotation.code()) && StrUtil.equals(map.getStr(annotation.code()), annotation.result())) {
                return Boolean.TRUE;
            }
        } catch (Exception e) {
            return Boolean.FALSE;
        }
        // 如果结果类型不匹配以上任何一种，返回false
        return Boolean.FALSE;
    }

    /**
     * 匹配方法监控的异常
     *
     * @param annotation 方法监控注解
     * @param exception  抛出的异常
     * @return 是否匹配
     */
    @Override
    public boolean match(Method method, MethodMonitor annotation, Throwable exception) {
        if (ObjectUtil.isNull(exception)) {
            return Boolean.FALSE;
        }
        // 遍历异常类型数组，检查是否与抛出的异常类型匹配
        for (Class<? extends Throwable> ex : annotation.exceptions()) {
            if (ex.equals(exception.getClass()) || ex.isAssignableFrom(exception.getClass())) {
                return Boolean.TRUE;
            }
        }
        // 如果没有匹配的异常类型，返回false
        return Boolean.FALSE;
    }
}